#ifndef EVENTLOOP_H
#define EVENTLOOP_H

#pragma once
// #include <pub.hpp>
#include "Epoll.h"
#include <queue>
#include <functional>
#include <sys/eventfd.h>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <atomic>
#include "Connection.h"

class EventLoop
{
public:
    EventLoop(int maxEvent = 1000);
    ~EventLoop();
    Epoll* getEpPtr() {return &ep_;}
    void updateChannel(Channel* ch) {ep_.updateChannel(ch);}
    void removeChannel(Channel* ch) {ep_.removeChannel(ch);}
    void insertConn(int fd, Connection* conn) {
        fds_.insert({fd, conn});
    }
    void Loop();
    void stop();

    bool isIOThread();
    void addTask(std::function<void()> task);
    // 唤醒 之后要去处理任务队列
    void wakeup();
    void handleWakeup();
    // 清理超时链接
    void handleTimer();
    void closeConn(int fd) {
        // 只需要删除epoll中的fd，不需要删除Connection， 释放资源在TcpServer中
        fds_.erase(fd);
    }
    bool isRunning() {return isRunning_;}
private:
    std::atomic_bool isRunning_ = false;
    Epoll ep_;
    int wakeupFd_;
    Channel* wakeCh_;

    // 定时器每五秒轮询一下, 后面可以传值
    int duration_ = 5;
    int timeout_ = 5;
    int timerFd_;
    Channel* timerCh_;
    // 记录了当前循环下的fd， 主循环下不用保留，主循环只负责接收连接
    std::unordered_map<int, Connection*> fds_;
    // 记录是不是IO线程id
    std::thread::id threadId_;
    std::mutex queMtx_;
    std::queue<std::function<void()>> tasks_;
};

#endif